/*******************************************************************
 * 
 *  Copyright C 2005 by Amlogic, Inc. All Rights Reserved.
 *
 *  Description: UPnP specific playlist code.
 *
 *  Author: Amlogic, Inc.
 *  Created: 4/3/2006 10:29PM
 *
 *******************************************************************/

#include "includes.h"
#include "aw_windows.h"
#include "aw_playlist.h"
#include "filenav.h"
#include "pathnav.h"
#include <string.h>
#include <aw_playlist2.h>

#include "fs_playlist.h"
#include "../user.h"

unsigned filelist_music[MAX_FILE_NODIR];
unsigned filelist_video[MAX_FILE_NODIR];
int total_count_music = 0;
int total_count_video = 0;

#ifdef TXT_PLAYER
unsigned filelist_txt[MAX_FILE_NODIR];
int total_count_txt = 0;
#endif

extern INT32U NODIR_FLAG;  //0 for with dir, 1 for playing music without dir, 2 for playing video without dir ,3 for playing txt without dir
extern int play_queue_getwhole(CHARSTR* path_name,INT32U media_type,INT32U file_nav_flag,QUEUE_HEAD_INFO** play_queue,INT32S search_way,unsigned* filelist);

char gCurOnlyFileName[256] ;
char gCurOnlyMp3FileName[256] ;

#define Way_Process(way,data) {data = (way)?(data-1):(data+1);}

typedef struct {
    unsigned        media_type;
    PlaylistType_t  list_type;
    int 			search_way;
    unsigned        start_index;
    unsigned        cur_num;
    unsigned        cur_index;
    Playlist_t     *playlist;
    char           *pathname;
    unsigned        pathname_len;
    char           *total_name;
} FSPlaylist_t;

unsigned char test_enable = 1;
QUEUE_HEAD_INFO* audio_play_queue = NULL;
QUEUE_HEAD_INFO* video_play_queue = NULL;
QUEUE_HEAD_INFO* image_play_queue = NULL;
QUEUE_HEAD_INFO* check_play_queue = NULL;

QUEUE_HEAD_INFO* play_queue_1 = NULL;
QUEUE_HEAD_INFO** play_queue_2 = NULL;
QUEUE_NODE_INFO* cur_node;
int search_way = 0;
extern void FileListInitData();
/* Callback from the playlist manager to clean up our context */
static void
fs_pl_delete(Playlist_t *playlist, void *context)
{
    FSPlaylist_t *fsl = context;
	switch(fsl->list_type){
		case PLAYLIST_TYPE_AUDIO:
    if(audio_play_queue)
	play_queue_release(&audio_play_queue);
			break;
		case PLAYLIST_TYPE_VIDEO:
	if(video_play_queue)
	play_queue_release(&video_play_queue);
			break;
		case PLAYLIST_TYPE_IMAGE:
	if(image_play_queue)
	play_queue_release(&image_play_queue);   
			break;	
		default:
			break;			
	}	
    if(fsl->search_way)
    {	     
    	FileListInitData();  
	}
	AVMem_free(fsl->pathname);
	AVMem_free(fsl);  
}

/* Playlist request function. */
static PlaylistStatus_t
fs_pl_get(Playlist_t *playlist, 
            int item_offset,
            void *context)
{
    int len;
    int i = ((item_offset>0)?item_offset:0) ;
    FSPlaylist_t *fsl = context;
    PlaylistItem_t *pli;
    INT32U get_list_num;
    PATHNODE file_list ;
    INT8U direction = 0 ;
    INT32U media_type=fsl->media_type&NAV_PATH_TYPE;
    unsigned retry = 0;
	int temp_offset = i ;
	int total_files_in_dir = 0;
	switch(fsl->list_type){
		case PLAYLIST_TYPE_AUDIO:
			play_queue_1 = audio_play_queue;
			break;
		case PLAYLIST_TYPE_VIDEO:
			play_queue_1 = video_play_queue;	
			break;
		case PLAYLIST_TYPE_IMAGE:
			play_queue_1 = image_play_queue;	
			break;			
		default:
			break;			
	}	
	play_queue_locate(play_queue_1,temp_offset);
	cur_node = play_queue_node_get(play_queue_1);
	total_files_in_dir = cur_node->file_end_pos - cur_node->file_start_pos+1;
	if(strcmp(fsl->pathname,cur_node->node_name) != 0)	
	{			
		reset_cur_path_node(NULL);
		FileNavCD(cur_node->node_name);
		fsl->pathname_len = strlen(cur_node->node_name);
		if(fsl->pathname)
		AVMem_free(fsl->pathname);
		fsl->pathname=AVMem_umalloc(fsl->pathname_len*2 + SHORT_NAME_LENGTH + 2);		
        memcpy(&(fsl->pathname[0]), cur_node->node_name,fsl->pathname_len+1);
        fsl->total_name = fsl->pathname + fsl->pathname_len + 1 ;
        memcpy(&(fsl->total_name[0]), cur_node->node_name,fsl->pathname_len+1);     
        fsl->start_index = cur_node->file_start_index ;
        fsl->cur_index  = fsl->start_index;
//	        fsl->cur_num = temp_offset - cur_node->video_start_pos;
		temp_offset -= cur_node->file_start_pos;
		fsl->cur_num = 0 ;
	}
	else{
//			fsl->cur_num = temp_offset - cur_node->video_start_pos;
		temp_offset -= cur_node->file_start_pos;
	}
/*improve the playlist access speed*/	

	if(cur_node->file_end_index > 0){		
		if(temp_offset >  (fsl->cur_num + total_files_in_dir/2)){
			fsl->cur_num = total_files_in_dir - 1;
			fsl->cur_index = cur_node->file_end_index ;
	    }
	}			

	i = temp_offset ;
    if(i == 0) {
        get_list_num = 1 ;
        int tryagain=1;
again:       FileNavGetNextFileListRandom(fsl->pathname, fsl->start_index, &file_list, &get_list_num, media_type) ;
        if((get_list_num == 0) || (file_list.path_type & NAV_IS_DIR)) {
        	if(tryagain){
        		tryagain=0;
        		goto again;
        	}
        	else        		
            return PLAYLIST_STATUS_ERROR;
        }
        fsl->cur_index = file_list.index ;
        fsl->cur_num = 0 ;
    }
    else {
        if(i < fsl->cur_num) {
            direction = 1 ;
        }
        while(1) {
            get_list_num = 1 ;
            int again=1;
 getagain:   if(direction) {
                FileNavGetPrevFileListRandom(fsl->pathname, fsl->cur_index, &file_list, &get_list_num, media_type) ;
            }
            else {
                FileNavGetNextFileListRandom(fsl->pathname, fsl->cur_index, &file_list, &get_list_num, media_type) ;
            }
            if(get_list_num == 0) {
            	if(again){
            		again=0;
            		goto getagain;
            	}else
                return PLAYLIST_STATUS_ERROR;
            }
            if(file_list.path_type & NAV_IS_DIR) {
                Way_Process(direction,fsl->cur_index) ;
                continue ;
            }
            fsl->cur_index = file_list.index ;
            if(i == fsl->cur_num) {
                break ;
            }
            Way_Process(direction,fsl->cur_num) ;
            Way_Process(direction,fsl->cur_index) ;
        }
        
    }

    len=strlen(file_list.short_name);
    memcpy(&(fsl->total_name[fsl->pathname_len]),file_list.short_name,len);

    fsl->total_name[fsl->pathname_len+len]=0;
    retry = 0;
RETRY:
    pli = AWCreatePlaylistItem(fsl->total_name, "");

    if(pli) {
        AWPlaylistResult(fsl->playlist, pli, PLAYLIST_STATUS_OK);
    } else {
        if(!(retry++)) {
            AWFlushPlaylistHistory(fsl->playlist);
            goto RETRY;
        }
        AWPlaylistResult(fsl->playlist, NULL, PLAYLIST_STATUS_ERROR);
    }

    return PLAYLIST_STATUS_ASYNCH;
}


static PlaylistStatus_t
fs_pl_get_nodir(Playlist_t *playlist, 
            int item_offset,
            void *context)
{
    int i = ((item_offset>0)?item_offset:0) ;
    FSPlaylist_t *fsl = context;
    PlaylistItem_t *pli;
    INT8U direction = 0 ;
    INT32U media_type=fsl->media_type&NAV_PATH_TYPE;
    unsigned retry = 0;
    int temp_offset = i ;


//    fsl->start_index = item_offset;
    fsl->cur_index = item_offset;
    
    if (NODIR_FLAG ==  1)
        strcpy(fsl->total_name, (char *)filelist_music[item_offset]);
    if (NODIR_FLAG ==  2)
        strcpy(fsl->total_name, (char *)filelist_video[item_offset]);
#ifdef TXT_PLAYER
    if (NODIR_FLAG ==  3)
        strcpy(fsl->total_name, (char *)filelist_txt[item_offset]);
#endif
RETRY:
    pli = AWCreatePlaylistItem(fsl->total_name, "");

    if(pli) {
        AWPlaylistResult(fsl->playlist, pli, PLAYLIST_STATUS_OK);
    } else {
        if(!(retry++)) {
            AWFlushPlaylistHistory(fsl->playlist);
            goto RETRY;
        }
        AWPlaylistResult(fsl->playlist, NULL, PLAYLIST_STATUS_ERROR);
    }

    return PLAYLIST_STATUS_ASYNCH;
}



static void
fs_pl_delete_nodir(Playlist_t *playlist, void *context)
{
	
}

Playlist_t *
fs_playlist_create_nodir(char* path_name ,unsigned media_type, 
                     PlaylistType_t list_type,
                     int c_index,int search_way,unsigned* app_type)
{
    FSPlaylist_t *fsl;
    Playlist_t *pl = NULL;
    INT32S total_count = 0;
    INT32S s_index = -1;
    INT32S c_num = -1;
    char* pname = NULL;
    
    
 //   AWClearPlaylist(media_type) ;

#if 0 
	switch(list_type){
			case PLAYLIST_TYPE_AUDIO:
				play_queue_2 = &audio_play_queue;				
				break;
			case PLAYLIST_TYPE_VIDEO:
				play_queue_2 = &video_play_queue;	
				break;
			case PLAYLIST_TYPE_IMAGE:
				play_queue_2 = &image_play_queue;	
				break;			
	}	
	if(path_name == NULL){
		pname=FileNavGetCurrDir();
	}
	else{
		pname = path_name;
	}
	total_count = play_queue_get(pname,media_type,SHOW_NORMAL_FILES,play_queue_2,search_way,c_index, &c_num,app_type,0);
	cur_node = play_queue_node_get(*play_queue_2);
	s_index = cur_node->file_start_index ;
#else
    if (list_type == PLAYLIST_TYPE_AUDIO)
        total_count = total_count_music;
    if (list_type == PLAYLIST_TYPE_VIDEO)
        total_count = total_count_video;
#ifdef TXT_PLAYER
    if (list_type == PLAYLIST_TYPE_IMAGE)
        total_count = total_count_txt;
#endif
#endif	
    if(total_count<=0)   
        return NULL;
    
    fsl = AVMem_umalloc(sizeof(*fsl));
    if(fsl) {
        bzero(fsl, sizeof(*fsl));

        fsl->pathname_len=strlen(pname);

        fsl->pathname=AVMem_umalloc(fsl->pathname_len*2 + SHORT_NAME_LENGTH + 2);
        if(!(fsl->pathname))
            goto exit;
            
        fsl->total_name = fsl->pathname + fsl->pathname_len + 1 ;

        memcpy(fsl->pathname,pname,fsl->pathname_len+1);     
        memcpy(fsl->total_name,pname,fsl->pathname_len+1);        

        fsl->media_type = media_type;
        fsl->start_index = s_index;
        fsl->cur_index = c_index;
        fsl->cur_num = c_index;
		fsl->list_type = list_type;
		fsl->search_way = search_way;
	      	pl = AWPlaylistInit2(fs_pl_get_nodir,
                             		fs_pl_delete_nodir,
                             		fsl->cur_num, 
                             		total_count,
                             		PLAY_MODE_NORMAL,
                             		list_type,
                             		fsl);
	
        if(!pl) {
exit:            
            AVMem_free(fsl);
            
            return NULL;
        }
        
        fsl->playlist = pl;
    }

    return pl;
}

int fs_filelist_create_nodir(char* path_name ,unsigned media_type, 
                     PlaylistType_t list_type,
                     int search_way)
{
    Playlist_t *pl = NULL;
    INT32S total_count_nodir = 0;
    char* pname = NULL;
    QUEUE_HEAD_INFO*   head = NULL;    

    if(path_name == NULL){
        pname=FileNavGetCurrDir();
    }
    else{
        pname = path_name;
    }
    if (list_type == PLAYLIST_TYPE_AUDIO) {	
        total_count_nodir = play_queue_getwhole(pname, MEDIA_MP3, list_type, &head, search_way, filelist_music);	
        total_count_music = total_count_nodir;
    }
    if (list_type == PLAYLIST_TYPE_VIDEO ) {	
        total_count_nodir = play_queue_getwhole(pname, AW_VIDEO_LIST, list_type, &head, search_way, filelist_video);	
        total_count_video = total_count_nodir;
    }
#ifdef TXT_PLAYER
    if (list_type == PLAYLIST_TYPE_IMAGE) {	
        total_count_nodir = play_queue_getwhole(pname, MEDIA_TXT, list_type, &head, search_way, filelist_txt);	
        total_count_txt = total_count_nodir;
    }
#endif

    return total_count_nodir;
}

Playlist_t *
fs_playlist_create(unsigned char* path_name ,unsigned media_type, 
                     PlaylistType_t list_type,
                     int c_index,int search_way,unsigned* app_type)
{
    FSPlaylist_t *fsl;
    Playlist_t *pl = NULL;
    INT32S total_count;
    INT32S s_index = -1;
    INT32S c_num = -1;
    char* pname;
    
    AWClearPlaylist(media_type) ;

#if 1
	switch(list_type){
			case PLAYLIST_TYPE_AUDIO:
				play_queue_2 = &audio_play_queue;				
				break;
			case PLAYLIST_TYPE_VIDEO:
				play_queue_2 = &video_play_queue;	
				break;
			case PLAYLIST_TYPE_IMAGE:
				play_queue_2 = &image_play_queue;	
				break;			
	}	
	if(path_name == NULL){
		pname=FileNavGetCurrDir();
	}
	else{
		pname = path_name;
	}
	total_count = play_queue_get(pname,media_type,SHOW_NORMAL_FILES,play_queue_2,search_way,c_index, &c_num,app_type,0);
	cur_node = play_queue_node_get(*play_queue_2);
	s_index = cur_node->file_start_index ;
#else
//    total_count=PrepareLocalPlayList(media_type, &s_index, c_index, &c_num) ;
#endif	
    if(total_count<=0)   
        return NULL;
    
    fsl = AVMem_umalloc(sizeof(*fsl));
    if(fsl) {
        bzero(fsl, sizeof(*fsl));

        fsl->pathname_len=strlen(pname);

        fsl->pathname=AVMem_umalloc(fsl->pathname_len*2 + SHORT_NAME_LENGTH + 2);
        if(!(fsl->pathname))
            goto exit;
            
        fsl->total_name = fsl->pathname + fsl->pathname_len + 1 ;

        memcpy(fsl->pathname,pname,fsl->pathname_len+1);     
        memcpy(fsl->total_name,pname,fsl->pathname_len+1);        

        fsl->media_type = media_type;
        fsl->start_index = s_index;
        fsl->cur_index = c_index;
        fsl->cur_num = c_num;
		fsl->list_type = list_type;
		fsl->search_way = search_way;
        pl = AWPlaylistInit2(fs_pl_get,
                             fs_pl_delete,
                             fsl->cur_num, 
                             total_count,
                             PLAY_MODE_NORMAL,
                             list_type,
                             fsl);

        if(!pl) {
exit:            
            AVMem_free(fsl);
            
            return NULL;
        }
        
        fsl->playlist = pl;
    }

    return pl;
}
int check_media_file_exist(unsigned char* path_name ,unsigned media_type,int search_way)
{
	INT32S c_num = -1;
    char* pname;
    INT32S total_count;
    unsigned app_type;
    int c_index = 0;
    play_queue_2  = &check_play_queue;    
	if(path_name == NULL){
		pname=FileNavGetCurrDir();
	}
	else{
		pname = path_name;
	}	
	total_count = play_queue_get(pname,media_type,SHOW_NORMAL_FILES,play_queue_2,search_way,c_index, &c_num,&app_type,1);
	if(check_play_queue)
	play_queue_release(&check_play_queue);   
	if(total_count){
		return 1;			/*file exist*/
	}else{
		return 0;			/*file not exist*/
	}	
}

int GetFirstPlaylistIndex(INT32U get_media_type)
{
    INT32U get_list_num;
    int r=-1;
    PATHNODE file_list ;
    INT32U media_type=get_media_type&NAV_PATH_TYPE;
    FileNavSeek(0) ;
    
    get_list_num = 1;
    while(get_list_num)
    {
    	FileNavGetNextFileList(&file_list, &get_list_num, media_type);
     	if((get_list_num)&&(!(file_list.path_type&NAV_IS_DIR)))
     	{
     		r=file_list.index;
       		break;
    	}    
    }
    return r;
}
